#ifndef __EventLoop_H
#define __EventLoop_H
#include "header.h"
#include "noncopyable.hpp"
#include <vector>
#include <unordered_map>
#include <functional>
#include <memory>
#include <iostream>
#include <functional>
#include <cstring> // for strerror()
#include "mutexlock.hpp"

namespace moqi
{

class Acceptor;
class TcpConnection;
using TcpConnectionPtr = std::shared_ptr<TcpConnection>;
using TcpConnecitonCallback = std::function<void(TcpConnectionPtr)>;
using event_t = struct epoll_event;//结构体，告诉内核要监听什么事件
using Functor = std::function<void()>;
class EventLoop:Noncopyable
{
public:
    EventLoop(Acceptor &acceptor, int max_events = 1024, int initSec = 1, int peridoSec = 100);
   ~EventLoop();
    void loop();
    void unloop();
    void sendInLoop(Functor &&cb);
    void waitEvent(int timeoutMs = 3000);
    void setAllCallback(TcpConnecitonCallback &&cb1,
                        TcpConnecitonCallback &&cb2,
                        TcpConnecitonCallback &&cb3)
    {
        _onConnection = std::move(cb1);
        _onMessage = std::move(cb2);
        _onClose = std::move(cb3);

    };

    void wakeup();//
private:
    void handleread(int fd);//清理事件标志
                            
    void add(int fd, uint32_t Epoll_events = EPOLLIN);
    void del(int fd);
    void mod(int fd, uint32_t Epoll_events);

    void handleConnection();//处理新链接到来事件
    void handleTimeOut();;//处理客户端超时踢出事件.或者其他定时事件
    void handleMessage(int);//处理有消息来事件 
    void sendReplays();//回复消息

    int createEpollFd();//创建epoll文件描述符
    int createEventFd();//创建线程通知的文件描述符
    int createTimeFd(int initSec, int peridoSec);//创建定时器的文件描述符

private:
    int                                         _epollfd;//epoll监听文件描述符
    int                                         _eventfd;//用于线程通知的fd
    int                                         _timefd;//定时器的文件描述符
    int                                         _max_events; // 最大事件数
    bool                                        _isLooping;//标志循环结束
    MutexLock                                   _mutex;//封装的互斥锁
    Acceptor&                                   _acceptor;//事件分发器                                                               
    std::vector<event_t>                        _events; // 存放就绪事件的数组
    std::unordered_map<int, TcpConnectionPtr>   _connects; // 文件描述符到回调函数的映射                               
    std::vector<Functor>                       _sendReplays;//回复消息的事件
    //以下3个回调函数，不会调用，而是存储起来，赋值给每一个新链接：
    TcpConnecitonCallback                       _onConnection;//处理连接完成后事件
    TcpConnecitonCallback                       _onMessage;//处理消息到来
    TcpConnecitonCallback                       _onClose;//处理链接关闭后的事件

};

}//end of namespace moqi
#endif //!EventLoop_H

